package org.example.c2;

import lombok.extern.slf4j.Slf4j;

/**
 * @author liu-rui
 * @date 2020/6/3 下午3:18
 * @description 通过CAS解决线程安全问题
 * @since
 */
@Slf4j
public class Demo6 {
    public static void main(String[] args) throws InterruptedException {
        SumTask sumTask = new SumTask();
        sumTask.exec(new Counter());
    }

    static class Counter implements ICounter {
        private volatile int sum;
        private static long sumFieldOffset;

        static {
            try {
                sumFieldOffset = MyUnSafe.getUnsafe().objectFieldOffset(Counter.class.getDeclaredField("sum"));
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void add(int data) {
            //方案１
//            MyUnSafe.getUnsafe().getAndAddLong(this, sumFieldOffset, data);
// 方案２
            while (true) {
                int old = MyUnSafe.getUnsafe().getIntVolatile(this, sumFieldOffset);

                if (MyUnSafe.getUnsafe().compareAndSwapInt(this, sumFieldOffset, old, old + data)) {
                    break;
                }
            }
        }

        @Override
        public int getSum() {
            return sum;
        }
    }
}